<?
include_once 'RegeDB.class.php';
include_once 'Encryption.class.php';
include_once 'functions.php';

/**
 * @name PHP 5 Login Class
 * @version 1.0
 * @abstract PHP 5 Login Class with support for MySQL databases
 **/

class RegeAuth {
    /* Custom Error Message for a field left blank */
    const MSG_INCOMPLETE_DATA = "You must supply both username and password. Please try again.";
    /* Custom Error Message for an invalid login */
    const MSG_INCORRECT_DATA = "Wrong username or password. Please try again. Note: Password is case-sensitive.";
    /* Custom Error Message when a user has 5 or more invalid logins */
    const ERROR_BANNED_LOGIN = "Sorry, you have been banned from viewing this page!";
    const MSG_LOGIN_ERROR = "There was an error during login. Consult your administrator.";
    const MSG_FORMAT_ERROR = "Incorrect data format.";
    const MSG_UNACTIVED = "Sorry, your account is not active.";
    
    private $username;
    private $password;
    private $userLevel;
    private $db;
    private $dbQuery;
    
    
    private static $regeAuth;
    /* Runs when an instance of the class is created. It automatically connects to the MySQL server
		and checks if the IP is not banned before contining 
		*/
    private function __construct() {
        $this->db = RegeDB::getInstance ();
    }
    
    public static function getInstance(){
        
        if ( !self::$regeAuth ){
            self::$regeAuth = new RegeAuth();
        }

        return self::$regeAuth;
    } 
    
    /* Return the username of a member*/
    public function getUsername() {
        return $this->username;
    }
    
    /* Return the plain text password of a member */
    public function getPassword() {
        return $this->password;
    }
    
    /* Return the encrypted password of a member */
    public function getEncryptedPassword() {
        return sha1 ( $this->password );
    }
    
    /* Get a member's IP Address */
    public function getUserIP() {
        return getenv ( "REMOTE_ADDR" );
    }
    
    /* Get a member's level */
    public function getUserLevel() {
        return $this->userLevel;
    }
    
    /* Validate an email is in the correct format e.g. someone@somewhere.com */
    public function validateEmail($email) {
        if (! filter_var ( $email, FILTER_VALIDATE_EMAIL )) {
            return false;
        }
        return true;
    }
    
    public function checkUserIsLogged() {
        if (isset ( $_COOKIE ['cookie_id'] ) && isset ( $_COOKIE ['cookie_role'] ) && isset ( $_COOKIE ['cookie_imgDir'] ))
            return true;
        else
            return false;
    }
    
    public function checkUserPass($email, $pass) {
        if ($this->validateEmail ( $email )) {
            $email = escapeit ( trim ( $email ) );
            $pass = Encrypt_new ( escapeit ( trim ( $pass ) ) );
            $this->dbQuery = $this->db->query ( "SELECT * FROM duser WHERE email='$email' AND passwd='$pass'" );
            if ($this->db->getAffectedRows () > 0) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    
    /**
     * Displays error message into form - sends via JSON! and breaks execution.  
     * @param string $message (optional) message which will be echoed on login screen
     */
    private function displayErrorMessage($message = null) {
        $arrJson = array ("success" => false, 'errorMessage' => $message );
        echo json_encode ( $arrJson );
        ob_end_flush ();
        die ();
    }
    
    /**
     * Displays error message into form - sends via JSON! and breaks execution.  
     * @param string $message (optional) message which will be echoed on login screen
     */
    private function displaySuccessMessage() {
        $arrJson = array ("success" => true );
        echo json_encode ( $arrJson );
        ob_end_flush ();
        die ();
    }
    
    /**
     * Displays login form. simple and effective.
     */
    private function displayLoginForm() {
        header ( 'Location:' . REGE_APP_DIR . 'homepage/index.php' );
        ob_end_flush();
        die();
    }
    
    /**
     * Simple Encrypting function, for managing passwords.
     * Taken from some user from PHP manual, little modified with bin2hex :)
     * @param string $param string which to encrypt
     * @return string Encrypted string 
     */
    private function secureEncrypt($param) {
        $crypted = (bin2hex ( crypt ( md5 ( $param ), md5 ( $param ) ) ));
        return $crypted;
    }
    
    private function startLoginSession() {
        $row = $this->db->fetch_array ( $this->dbQuery );
        
        $inTwoMonths = 60 * 60 * 24 * 60 + time ();
        
        $domain = ($_SERVER ['HTTP_HOST'] != 'localhost') ? $_SERVER ['HTTP_HOST'] : false;
        
        $past = time () - 10;
        setcookie ( "cookie_id", 0, $past, '/', $domain, false );
        setcookie ( "cookie_role", 0, $past, '/', $domain, false );
        
        setcookie ( "cookie_id", $row ['id'], $inTwoMonths, '/', $domain, false );
        setcookie ( "cookie_role", $row ['role'], $inTwoMonths, '/', $domain, false );
        
        // hardcode image directory to '4083238319' now.
        setcookie ( "cookie_imgDir", '4083238319', $inTwoMonths, '/', $domain, false );
        
        $this->userLevel = $row ['role'];
    }
    
    
    /**
     * Main function. Does all login stuff.
     * checks whether user is loged, authenticates and controls all stuff.
     * @param void 
     */
    public function doLogin() {
        if ($this->checkUserIsLogged ()) { //user is logged in. Proceed. 
            $this->displaySuccessMessage();
            
        } else { //user is not logged. Checks if user typed data into login form:
            
            if (isset ( $_POST ["userName"] ) && isset ( $_POST ['userPass'] )) { //User typed login data, proceed to check:
                
                if (! $_POST ["userName"] || ! $_POST ["userPass"]) { //not completed data entered. display error!
                    $this->displayErrorMessage ( self::MSG_INCOMPLETE_DATA );
                    
                } else { //userName and userPass are posted, filter and check them!
                    
                    if ($this->checkUserPass ( $_POST ["userName"], $_POST ['userPass'] )) { //checked and correct user/pass, start login session:
                        $this->startLoginSession ();
                        if ($this->userLevel == "0") {
                            $this->displayErrorMessage ( self::MSG_UNACTIVED );
                        } else {
                            $this->displaySuccessMessage();
                        }
                        //LoginForm takes control!
                        $this->db->free_result ( $this->dbQuery );
                    } else { //userName/pass not Correct, return to login form with error message.
                        $this->displayErrorMessage ( self::MSG_INCORRECT_DATA );
                        //LoginForm takes control!
                    }
                }
            } else { //user is neither logged, nor he typed login data. Display LoginForm! 
                $this->displayErrorMessage ( self::MSG_INCOMPLETE_DATA );
            }
        }
        
    }
    
    
    public function doLogout() {
        $domain = ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
        if(isset($_COOKIE['cookie_id'])){
            $past = time() - 10;
            setcookie("cookie_id", 0, $past, '/', $domain, false);
            setcookie("cookie_role", 0, $past, '/', $domain, false);
        }
    }

}
?>